#include "PatientValueEventClient.h"
#include "Patient.h"
#include "Display.h"
#include <iostream>
#include <iomanip>

using namespace std;

PatientValueEventClient::PatientValueEventClient(IReactor<SOCKET> *reactor)
	:ServiceHandler(reactor)
{
#ifdef STOPWATCH
	stopwatch = Stopwatch();
#endif
}

PatientValueEventClient::~PatientValueEventClient(void)
{
}

bool PatientValueEventClient::open(SOCK_Stream* st)
{
	peer() = *st;
	handle.setConnection(st->get_handle());
	reactor->register_handler(this, INIT_EVENT);
	return true;
}

void PatientValueEventClient::handle_event(Handler<SOCKET> handle, Event_Type et)
{
	if(INIT_EVENT == et)
	{
		cout << "Initialization with server completed" << endl;
		reactor->remove_handler(this, INIT_EVENT);
		stream.send("",0);
		newCprRequest();
	}
	else if(WRITE_EVENT == et)
	{
		cout << "Requesting patient: " << cprNr << endl;
		stream.send(cprNr,0);
		reactor->remove_handler(this, WRITE_EVENT);
		reactor->register_handler(this, READ_EVENT);
	}
	else if(READ_EVENT == et)
	{
		reactor->remove_handler(this, READ_EVENT);
		handleReceivedInfo();
	}
	else
	{
		cout << "Other event than INIT have been received" << endl;
	}
}

void PatientValueEventClient::newRequest()
{
	char tryAgain[20]={};
	bool validInput = true;

	do{
		cout << endl << "Press 'N' for new patient request or 'E' for exiting :" << endl;
		cin >> tryAgain;

		if('E' == *tryAgain || 'e' == *tryAgain)
		{
			closeConnection();
			validInput=true;
		}
		else if('N' == *tryAgain || 'n' == *tryAgain)
		{
			newCprRequest();
			validInput=true;
		}
		else
		{
			cout << "Undefined command... Try again" << endl << endl;
			validInput = false;
		}
	}while(false == validInput);
}

void PatientValueEventClient::newCprRequest()
{
	cout << endl << "Enter CPR number (xxxxxxxxxx): " << endl;
	cin >> cprNr;
#ifdef STOPWATCH
	stopwatch.start();
#endif
	reactor->register_handler(this, WRITE_EVENT);
}

void PatientValueEventClient::handleReceivedInfo()
{
	const size_t length = 150;
	char buf[length];
	char checkForExit[sizeof(CLOSE_CONNECTION)];
	buf[stream.recv(&buf,length,0)]='\0';
	Patient patient;
	Display display;
	patient.set(buf,0x1F);
	cout << endl << endl;
	display.set(&patient);

	cout << endl << endl;
	cout << "Handling received information!" << endl;

	for(int i = 0; i < sizeof(CLOSE_CONNECTION); i++)
		checkForExit[i] = buf[i];

	if(0 == strcmp(checkForExit,CLOSE_CONNECTION))
		exit(0);
	else
	{
#ifdef STOPWATCH
		stopwatch.stop();
		size_t time;
		time = stopwatch.getDuration(stopwatch.MILLISECONDS);
		cout << "Time to make a request: " << time << " miliseconds" << endl;
#endif
		newRequest();
	}

}

void PatientValueEventClient::closeConnection()
{
	int i;
	for(i = 0; i < sizeof(CLOSE_CONNECTION); i++)
		cprNr[i] = CLOSE_CONNECTION[i];

	for(i; i < len; i++)
	{
		cprNr[i] = 0;
	}
	reactor->register_handler(this, WRITE_EVENT);
}